/*
 * Copyright (c) 2021-2021, WeiStudio
 *
 * License: Apache-2.0
 *
 * Change Logs:
 * Date           Author        Notes
 * 2021-07-13     WeiStudio     the first version
 */


#ifndef __QE_CORE_H__
#define __QE_CORE_H__


#include "autoconfig.h"
#include "qe_def.h"
#include "qe_service.h"
#include "qe_platform.h"
#include "qe_log.h"
#include "qe_bitmap.h"
#include <stdarg.h>



void qe_ringbuffer_init(struct qe_ringbuffer *rb, char *buf, unsigned int length);
void qe_ringbuffer_clear(struct qe_ringbuffer *rb);
void qe_ringbuffer_write(struct qe_ringbuffer *rb, char *buf, unsigned int len);
void qe_ringbuffer_read(struct qe_ringbuffer *rb, char *buf, unsigned int len);
unsigned int qe_ringbuffer_wait(struct qe_ringbuffer *rb);
unsigned int qe_ringbuffer_size(struct qe_ringbuffer *rb);
struct qe_ringbuffer *qe_ringbuffer_create(qe_size_t size);

void qe_ringq_init(struct qe_ringq *q, void *buf, qe_size_t elem_size, qe_size_t num_elems);
void qe_ringq_fromarray(struct qe_ringq *q, void *array, qe_size_t elem_size, qe_size_t num_elems);
qe_err_t qe_ringq_get(struct qe_ringq *q, int index, void *data);
qe_err_t qe_ringq_enq(struct qe_ringq *q, void *data, unsigned int num);
qe_err_t qe_ringq_deq(struct qe_ringq *q, void *data, unsigned int num);
qe_bool_t qe_ringq_isempty(struct qe_ringq *q);
qe_bool_t qe_ringq_isfull(struct qe_ringq *q);
unsigned int qe_ringq_wait(struct qe_ringq *q);
unsigned int qe_ringq_size(struct qe_ringq *q);
unsigned int qe_ringq_nbytes(struct qe_ringq *q);
struct qe_ringq *qe_ringq_create(qe_size_t elem_size, qe_size_t num_elems);

void qe_gbuf_init(struct qe_gbuf *buf, void *buffer, qe_size_t size);
void qe_gbuf_clear(struct qe_gbuf *buf);
void qe_gbuf_backoff(struct qe_gbuf *buf, int back);
struct qe_gbuf *qe_gbuf_create(qe_size_t size);
void qe_gbuf_pool_init(struct qe_gbuf_pool *pool);
void qe_gbuf_pool_clear(struct qe_gbuf_pool *pool);
qe_err_t qe_gbuf_append(struct qe_gbuf *buf, void *data, qe_size_t length);
qe_err_t qe_gbuf_pool_append(struct qe_gbuf_pool *pool, struct qe_gbuf *buf);
struct qe_gbuf *qe_gbuf_pool_merge(struct qe_gbuf_pool *pool);

qe_bool_t qe_minpq_isfull(struct qe_minpq *q);
qe_bool_t qe_minpq_isempty(struct qe_minpq *q);
unsigned int qe_minpq_wait(struct qe_minpq *q);
struct qe_minpq *qe_minpq_create(unsigned int elem_size, unsigned int num_elems, 
	qe_bool_t (*comparator)(void *, void *));
qe_err_t qe_minpq_get(struct qe_minpq *q, void *u, int *p, int index);
qe_err_t qe_minpq_del(struct qe_minpq *q, void *u, unsigned int *p, int index);
qe_err_t qe_minpq_insert(struct qe_minpq *q, void *u, int p);
qe_err_t qe_minpq_resize(struct qe_minpq *q, unsigned int capcaity);
qe_err_t qe_minpq_delmin(struct qe_minpq *q, void *e, unsigned int *p);

struct qe_queue *qe_queue_create(unsigned int elem_size, unsigned int num_elems, 
	unsigned int flags);
qe_err_t qe_queue_init(struct qe_queue *q, void *data, unsigned int elem_size, 
	unsigned int num_elems, unsigned int count, unsigned int flags);
qe_bool_t qe_queue_isempty(struct qe_queue *q);
qe_bool_t qe_queue_isfull(struct qe_queue *q);
unsigned int qe_queue_size(struct qe_queue *q);
qe_err_t qe_queue_get_elem(struct qe_queue *q, int index, void *elem);
qe_err_t qe_queue_get_elems(struct qe_queue *q, int index, void *elem, unsigned int num);
qe_err_t qe_queue_enq(struct qe_queue *q, void *elem);
qe_err_t qe_queue_enq_elems(struct qe_queue *q, void *elem, unsigned int num);
qe_err_t qe_queue_deq(struct qe_queue *q, void *elem);
qe_err_t qe_queue_deq_elems(struct qe_queue *q, void *elem, unsigned int num);

qe_u8 qe_checksum_u8(char *buf, unsigned int len);
qe_u32 qe_checksum_u32(char *buf, unsigned int len);

unsigned long int qe_htonl(unsigned long int x);
unsigned short int qe_htons(unsigned short int x);

void qe_assert_set_hook(void (*hook)(const char *, const char *, qe_size_t));
void qe_assert_handler(const char *ex_string, const char *func, qe_size_t line);

#define qe_assert(ex)                                                      	\
if (!(ex))                                                               	\
{                                                                         	\
    qe_assert_handler(#ex, __FUNCTION__, __LINE__);                       	\
}

void qe_set_errno(qe_err_t e);

qe_err_t qe_device_register(struct qe_device *dev,
                                          const char *name,
                                          qe_u16 flags);
qe_err_t qe_device_unregister(struct qe_device *dev);
struct qe_device *qe_device_find(const char *name);
qe_err_t qe_device_control(qe_device_t dev, int cmd, void *arg);
qe_err_t qe_device_close(struct qe_device *dev);
qe_err_t qe_device_open(struct qe_device *dev, qe_u16 oflag);
qe_size_t qe_device_read(struct qe_device *dev,
								 qe_off_t		   pos,
								 void             *buffer,
								 qe_size_t   size);
qe_size_t qe_device_write(struct qe_device *dev,
								 qe_off_t		   pos,
  								 const void       *buffer,
  								 qe_size_t         size);

qe_err_t 
qe_device_set_rx_indicate(struct qe_device *dev,
                          qe_err_t (*rx_ind)(struct qe_device *, qe_size_t));
qe_err_t qe_device_set_tx_complete(struct qe_device *dev,
                         					     qe_err_t (*tx_done)(struct qe_device *, void *));

/**
 * Memory Interface
 */
void  qemem_heap_set(void *start, qe_size_t size);
void  qemem_eapi_set(void* (*malloc)(qe_size_t size), 
							    void* (*zalloc)(qe_size_t size),
							    void* (*realloc)(void *buf, qe_size_t size),
							    void  (*free)(void *ptr));
qe_size_t qe_weak qemem_heap_get_freesize(void);

void qe_initcall(void);



void qe_assert_set_hook(void (*hook)(const char *, const char *, qe_size_t));
void qe_assert_handler(const char *ex_string, const char *func, qe_size_t line);

#define qe_assert(ex)                                                      	\
if (!(ex))                                                               	\
{                                                                         	\
    qe_assert_handler(#ex, __FUNCTION__, __LINE__);                       	\
}

unsigned long int qe_htonl(unsigned long int x);
unsigned short int qe_htons(unsigned short int x);


void qe_show_version(void);

qe_err_t qe_get_errno(void);
void qe_set_errno(qe_err_t e);
int *_qe_errno(void);
#ifndef errno
#define errno	*_qe_errno()
#endif



qe_workqueue_t *qe_workqueue_create(unsigned int size);
qe_err_t qe_workqueue_schedule(qe_workqueue_t *q, 
	qe_err_t (*handle)(qe_workqueue_t * , struct qe_worker *), 
	qe_u32 ts, void *data);
qe_time_t qe_workqueue_service(qe_workqueue_t *q, qe_u32 ts);

#endif /* __QE_CORE_H__ */


